package com.dingwen.treasure.base.convert.serializer;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.dingwen.treasure.base.enums.DesensitizationFunction;
import com.dingwen.treasure.base.service.DesensitizationService;
import com.dingwen.treasure.base.util.OptionalUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Optional;

/**
 * 　DesensitizationSerializer： TODO 原理功能
 * 　@author dingwen
 * 　@date 2022/7/19
 */
public class DesensitizationSerializer extends StdScalarSerializer<Object> {


    private static final long serialVersionUID = -414081303910499724L;

    /**
     * desensitizationService
     */
    private final DesensitizationService desensitizationService;

    public DesensitizationSerializer(DesensitizationService desensitizationService) {
        super(String.class, Boolean.FALSE);
        this.desensitizationService = desensitizationService;
    }

    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String content = Convert.toStr(o);
        Optional<DesensitizationService> optional = Optional.ofNullable(this.desensitizationService);
        assert desensitizationService != null;
        String desensitizationContent = OptionalUtil.objectHandler(
                () -> desensitizationService.desensitization(content, null),
                () -> DesensitizationFunction.ALL_MASK.getDesensitizationService().desensitization(content, null),
                optional);
        jsonGenerator.writeString(desensitizationContent);
    }

    @Override
    public boolean isEmpty(SerializerProvider provider, Object value) {
        return StrUtil.isEmpty(Convert.toStr(value));
    }

    @Override
    public void serializeWithType(Object value, JsonGenerator g, SerializerProvider provider, TypeSerializer typeSer) throws IOException {
        this.serialize(value, g, provider);
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
        return this.createSchemaNode("string", Boolean.TRUE);
    }

    @Override
    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
        this.visitStringFormat(visitor, typeHint);
    }
}
